<template>
  <page-container class="graph-container" :fullScreen="true">
    <div class="force-content" :class="{ 'full-screen': screenStatus }" ref="forceContent">
      <!-- 布局 -->
      <div class="layout">
        <label>布局：</label>
        <a-select
          v-model:value="layoutValue"
          placeholder="请选择布局"
          @change="layoutChange"
          :options="layoutOption"
        ></a-select>
      </div>
      <!-- 图例 -->
      <div class="legend">
        <ul>
          <li
            v-for="(val, key, index) in nodeGroup"
            @click="legendClick(key, index)"
            :class="{ 'item-selected': val._selected }"
          >
            <span :style="{ background: val._selected ? val.color : '' }"></span>
            {{ val.name }}
          </li>
        </ul>
      </div>
      <!-- 右侧工具栏 -->
      <!-- <tool-bar
        @equalZoom="equalZoom"
        @screen="screen"
        @refresh="refresh"
        @enlarge="enlarge"
        @reduce="reduce"
        @save="download"
    ></tool-bar> -->
      <!-- 图谱容器 -->
      <div id="container" ref="container"></div>
      <police-list-drawer
        v-model:visible="drawerVisible"
        portionUrl="/series/history/queryCaseList"
        :params="policeDrawerParams"
      ></police-list-drawer>
    </div>
  </page-container>
</template>

<script>
import {
  defineComponent,
  onMounted,
  onActivated,
  onUnmounted,
  getCurrentInstance,
  computed,
  ref,
  toRaw,
} from 'vue';
import { useRouter } from 'vue-router';
import { cloneDeep, random } from 'lodash';
import G6 from '@antv/g6';
// import toolBar from "./components/tupuToolbar"
// import { decodeURIParam, fullScreen, exitFullScreen, copy } from '@/service/UtilService';
import PoliceListDrawer from '@/components/police-list-drawer/index.vue';

import graphUtil, {
  getRootNode,
  getSubordinateData,
  graph2tree,
  addNodesForTree,
} from './js/graphUtil';
import styleMap from './js/nodeStyle';
import { layoutOption, layoutMap } from './js/layoutState';
import PathLayout from './js/pathLayout';
import './js/registerNode.js'; // 自定义节点注册
import { queryGraph } from '@/api/study-judge/force-graph';
let graph = null;

const defaultLayoutValue = 'Concentric'; // 同心圆布局
let currentGraphData = {};
let graphAllData = {};
let nodeData = {};
let layout = {
  type: '',
  instance: null,
  destroyed: true,
};
let CANVAS_WIDTH = 800,
  CANVAS_HEIGHT = 800;

export default defineComponent({
  name: 'forceGraph',
  data() {
    return {
      layoutValue: defaultLayoutValue,
      focusNode: false,
      screenStatus: false, //是否全屏
      zoomIndex: 1, //缩放层级
      nodeGroup: {},
      degree: 1, //当前度
      codes: '',
      drawerVisible: false,
      policeDrawerParams: {
        callTimeStart: '', // 开始时间
        callTimeEnd: '', // 结束时间
        callSummaryCodes: '', //接警类别
        dealSummaryCodes: '', //反馈类别
        xqdwCodes: '', //辖区单位
        classifyCodes: '', // 智能分类
        page: 1,
        size: 10,
        inputParams: '',
        caseNoList: '',
      },
    };
  },
  setup(props) {
    const { proxy } = getCurrentInstance(); // 获取当前组件实例
    const router = useRouter();
    const reuteQuery = computed(() => router.currentRoute.value.query);
    const pathLayout = ref(null);
    // 刷新图谱
    const refresh = () => {
      reset();
      proxy.layoutValue = defaultLayoutValue;
      queryGraphData();
    };

    // 重置画布
    const reset = () => {
      if (graph) {
        graph.off();
        graph.clear();
        graph.destroy();
        graph = null;
      }
    };
    // 获取图谱数据
    const queryGraphData = () => {
      let param = {
        seriesNo: reuteQuery.value.seriesNo, //串并编号
        callTimeStart: reuteQuery.value.callTimeStart, //开始时间
        callTimeEnd: reuteQuery.value.callTimeEnd, //结束时间
        inputParams: reuteQuery.value.inputParams, //输入参数
        xqdwCodes: reuteQuery.value.areaSort, //  辖区单位
        classifyCodes: reuteQuery.value.intelligentSort, // 智能分类编号
        callSummaryCodes: reuteQuery.value.alarmSort, // 报警类别
        dealSummaryCodes: reuteQuery.value.backSort, // 反馈类别
        degree: proxy.degree, //查询度
        // seriesType: reuteQuery.value.seriesType,
      };
      queryGraph(param)
        .then(res => {
          if (res.code && res.code == '200') {
            // res.data = this.createGraphData(res.data.nodeList,res.data.edgeList)
            res.data.edgeList = res.data.edgeList.map(o => {
              const { caseNos, caseNum, source, target } = o;
              //   const size = caseNum + 1;
              return {
                // size,
                caseNos,
                label: caseNum,
                source,
                target,
              };
            });
            const nums = res.data.nodeList.map(o => o.caseNum);
            const getDegreesDomain = nums => {
              var minDegree = 0;
              var maxDegree = 0;
              nums.forEach(function (n) {
                var degree = n;
                minDegree = Math.min(degree, minDegree);
                maxDegree = Math.max(degree, maxDegree);
              });
              return [Math.sqrt(minDegree), Math.sqrt(maxDegree)];
            };
            var degreesDomain = getDegreesDomain(nums);
            const getOptimumNum = (range, degreesDomain, num) => {
              const numScale = (range, domain, num) => {
                return (
                  ((num - domain[0]) * (range[1] - range[0])) / (domain[1] - domain[0]) +
                  range[0]
                ).toFixed(1);
              };
              var scale = numScale(range, degreesDomain, Math.sqrt(num));
              return Number(scale);
            };

            res.data.nodeList = res.data.nodeList.map(o => {
              const { caseNos, caseNum, className, id, label } = o;
              const size = getOptimumNum([20, 50], degreesDomain, caseNum);
              return {
                size,
                caseNos,
                class: o.class,
                className,
                id,
                caseNum,
                value: label,
                label: `${label}(${caseNum})`,
                x: 0,
                y: 0,
              };
            });
            proxy.createNodeGroup(res.data.nodeList);
            graphAllData = res.data;
            // proxy.setZindexById(reuteQuery.value.featureValue, 0);
            // pathLayout.value = new PathLayout(graph, toRaw(graphAllData));
            // const rootNode = getRootNode(res.data.nodeList);
            // pathLayout.value.addSpecialNodes(rootNode);
            if (graph) {
              proxy.updateGraph({
                nodeList: res.data.nodeList,
                edgeList: res.data.edgeList,
              });
            } else {
              proxy.$nextTick(() => {
                proxy.renderGraph({
                  nodeList: res.data.nodeList,
                  edgeList: res.data.edgeList,
                });
                proxy.bindListener();
              });
            }
          }
        })
        .catch(err => {
          console.log(err);
        });
    };

    const getInitGraphData = () => {
      //    return graphAllData
      const value = decodeURI(decodeURI(reuteQuery.value.featureValue));
      let data = proxy.getNeighborMixedData(value, 0);
      const { nodeList } = graphAllData;
      let node = nodeList.filter(o => o.id.indexOf(value) >= 0);
      data.nodeList = [...node, ...data.nodeList];
      return data;
    };
    onMounted(() => {
      window.addEventListener('resize', proxy.resizeHandle);
    });

    onActivated(() => {
      reset();
      queryGraphData(); // 请求列表接口
    });
    onUnmounted(() => {
      window.removeEventListener('resize', proxy.resizeHandle);
      reset();
    });
    return {
      layoutOption,
      pathLayout,
      reuteQuery,
    };
  },

  components: {
    PoliceListDrawer,
  },
  methods: {
    /**
     * 全屏
     * @param {Number} status 是否全屏的状态 0 代表非全屏 1 代表全屏
     */
    screen(status) {
      this.screenStatus = status;
      //   this.screenStatus ? fullScreen() : exitFullScreen();
    },
    /**
     * 等比缩放
     */
    equalZoom() {
      // console.log('等比缩放')
      this.zoomIndex = 1;
      const x = graph.getWidth() / 2;
      const y = graph.getHeight() / 2;
      graph.zoomTo(this.zoomIndex, { x, y });
    },

    /**
     * 放大图谱
     */
    enlarge() {
      const maxZoom = graph.getMaxZoom();
      if (this.zoomIndex >= maxZoom) return false;
      this.zoomIndex += 0.25;
      const x = graph.getWidth() / 2;
      const y = graph.getHeight() / 2;
      graph.zoomTo(this.zoomIndex, { x, y });
    },
    /**
     * 缩小图谱
     */
    reduce() {
      const minZoom = graph.getMinZoom();
      if (this.zoomIndex <= minZoom) return false;
      this.zoomIndex -= 0.25;
      const x = graph.getWidth() / 2;
      const y = graph.getHeight() / 2;
      graph.zoomTo(this.zoomIndex, { x, y });
    },
    /**
     * 下载图谱
     */
    download() {
      graph.downloadFullImage();
    },
    legendClick() {},
    /**
     * 图谱布局修改
     * @param {String} val 图谱布局标识
     */
    layoutChange(val) {
      this.$nextTick(() => {
        const container = document.getElementById('container');
        const width = container.scrollWidth;
        const height = container.scrollHeight - 30;
        const layoutConfig = layoutMap[val];
        layoutConfig.center = [width / 2, height / 2];
        console.log('layoutConfig', val, layoutConfig);
        graph.updateLayout(layoutConfig);
      });
      //     graph.fitView([20, 20]);
      //   graph.changeSize(width,height);
      //   graph.zoomTo(this.zoomIndex,{x:width/2,y:height/2});
    },
    /**
     * 创建节点分组数据用于图例展示交互
     * @param {Array} data
     */
    createNodeGroup(data) {
      let group = {};
      data.forEach(item => {
        if (styleMap[item.class]) {
          if (group[item.class]) {
            group[item.class].data.push(item);
          } else {
            group[item.class] = {
              data: [item],
              name: styleMap[item.class].name,
              _selected: true,
              color: styleMap[item.class].style.stroke,
            };
          }
        }
      });
      this.nodeGroup = group;
    },
    /**
     * @description: 获取当前节点的下个层级数据 【生成的 edges 重复，不全 】
     * @param {*}
     * @return {*}
     */
    getNeighborMixedData(id, zIndex) {
      const { nodeList, edgeList } = graphAllData;

      let findNextNodes = function (id, zIndex) {
        let data = {
          nodeList: [],
          edgeList: [],
        };
        edgeList.forEach(edge => {
          if (edge.target === id) {
            let list = currentGraphData.edges.filter(
              o => o.source === edge.source && o.target === edge.target,
            );
            !list.length && data.edgeList.push(edge);
            nodeList.forEach(o => {
              if (o.id === edge.source) {
                if (!o.zIndex && o.zIndex !== 0) {
                  o.zIndex = zIndex + 1;
                  data.nodeList.push(o);
                }
              }
            });
          } else if (edge.source === id) {
            let list = currentGraphData.edges.filter(
              o => o.source === edge.source && o.target === edge.target,
            );
            !list.length && data.edgeList.push(edge);
            nodeList.forEach(o => {
              if (o.id === edge.target) {
                if (!o.zIndex && o.zIndex !== 0) {
                  o.zIndex = zIndex + 1;
                  data.nodeList.push(o);
                }
              }
            });
          }
        });
        return data;
      };

      let data = findNextNodes(id, zIndex);
      return data;
    },
    setZindexById(id, zIndex) {
      const { nodeList } = graphAllData;
      nodeList.forEach(o => {
        if (o.id.indexOf(id) >= 0) {
          o.zIndex = zIndex;
        }
      });
    },
    getZindexById(id) {
      const { nodeList } = graphAllData;
      let zIndex = 0;
      nodeList.forEach(o => {
        if (o.id.indexOf(id) >= 0) {
          zIndex = o.zIndex || 0;
        }
      });
      return zIndex;
    },
    getNeighborMixedGraph(currentItem) {
      const id = currentItem._cfg.id;
      const zIndex = this.getZindexById(id);
      const data = this.getNeighborMixedData(id, zIndex);
      const expandData = this.processNodesEdges(data);
      const nodes = [].concat(currentGraphData.nodes, expandData.nodes);
      const edges = [].concat(currentGraphData.edges, expandData.edges);
      return { nodes, edges };
    },
    /**
     * @description: 刷新图
     * @param {*}
     * @return {*}
     */
    handleRefreshGraph(currentData) {
      try {
        // cachePositions = graphUtil.cacheNodePositions(graph.getNodes())
        // currentData.nodes.forEach(node=>{
        //     const cachePosition = cachePositions ? cachePositions[node.id] : undefined;
        //     if (cachePosition) {
        //         node.x = cachePosition.x;
        //         node.y = cachePosition.y;
        //         // node.new = false;
        //     } else {
        //         // node.new = isNewGraph ? false : true;
        //         // if (manipulatePosition && !node.x && !node.y) {
        //         //     node.x = manipulatePosition.x + 30 * Math.cos(Math.random() * Math.PI * 2);
        //         //     node.y = manipulatePosition.y + 30 * Math.sin(Math.random() * Math.PI * 2);
        //         // }
        //     }
        // })

        graph.changeData(currentData);
      } catch (error) {
        console.log('handleRefreshGraph 刷新图', error);
      }
    },
    /**
     * 创建图谱实例
     */
    createGraph() {
      if (!graph) {
        const container = document.getElementById('container');
        CANVAS_WIDTH = container.scrollWidth;
        CANVAS_HEIGHT = container.scrollHeight - 30;

        // 实例化 Menu 插件
        const menu = new G6.Menu({
          offsetX: 10,
          itemTypes: ['node', 'edge'],
          getContent(e) {
            // const nodeClass = e.item._cfg.model.class;
            // const hasSelectState = graphUtil.hasState(e.item, '_selected');
            // const menuItemDetailDisplay = nodeClass === 'case' ? 'block' : 'none';
            // style="display:${menuItemDetailDisplay}"

            return `<ul class="menu-content">
                   <li data-id="detail">查看详情</li>
                </ul>`;
            //    <li data-id="expand">展开</li>
          },
          handleMenuClick: (target, item) => {
            const { _cfg } = item;
            const hasSelectState = graphUtil.hasState(item, '_selected');
            const menuItemId = target.dataset.id;
            const label = _cfg.model.label;

            if (_cfg.type === 'node') {
              if (menuItemId === 'flag') {
                graph.setItemState(item, '_selected', !hasSelectState);
              }
              if (menuItemId === 'detail') {
                let id = _cfg.model.id;
                if (id.charAt(0) === 'O') {
                  // 警情数量大于1
                  this.codes = _cfg.model.codes;
                } else {
                  this.codes = _cfg.model.label;
                }

                const model = _cfg.model;
                console.log('model', model);
                this.policeDrawerParams.inputParams = model.value;
                this.policeDrawerParams.caseNoList = model.caseNos;
                this.policeDrawerParams.seriesNo = this.reuteQuery.seriesNo;
                this.drawerVisible = true;

                if (menuItemId === 'copy') {
                  copy(label, status => {
                    if (status === 'success') {
                      this.$message.success({
                        message: '复制成功',
                        duration: 800,
                      });
                    }
                  });
                }
              }
              if (menuItemId === 'expand') {
                // manipulatePosition = item._cfg.model;
                // const currentData = this.getNeighborMixedGraph(item);

                // const nextGraphData = getSubordinateData(
                //   item._cfg.model,
                //   graphAllData.edgeList,
                //   graphAllData.nodeList,
                // );
                // const nextGraphData_ = this.processNodesEdges(nextGraphData);
                // const lastData = Object.assign(
                //   {},
                //   {
                //     nodes: [].concat(currentGraphData.nodes, nextGraphData_.nodes),
                //     edges: [].concat(nextGraphData_.edges),
                //   },
                // );

                // currentGraphData = cloneDeep(lastData);

                // console.log('lastData', lastData);
                // graph.changeData(lastData);

                const data = this.pathLayout.extendNodes(item._cfg.model);
                const specialNodes = this.pathLayout.getSpecialNodes();
                const subgraphLayout = this.pathLayout.getSubgraphLayout(
                  item._cfg.model,
                  data,
                  graph,
                );

                const allData = {
                  nodes: [].concat(data.nodes, specialNodes),
                  edges: data.edges,
                };
                // const treeData = graph2tree(data.nodes);
                // addNodesForTree(graphAllData.nodeList, item._cfg.model, treeData.nodes);
                graph.read(allData);
                // graph.positionsAnimate();

                // graphAllData = lastData;

                // const nodes = graph.getNodes();
                // const edges = graph.getEdges();
                // console.log('item._cfg.model', item._cfg.model);
                // console.log('nodes', nodes);
                // const treeData = graph2tree(graphAllData.nodeList);
                // console.log('lastData', lastData);

                // tree layout
                /***/
                // const treeData = addNodesForTree(
                //   graphAllData.nodeList,
                //   item._cfg.model,
                //   nextGraphData_.nodes,
                // );

                graph.refresh();
                graph.paint();
                graph.refreshPositions();
              }
            }
          },
          shouldBegin: evt => {
            // let className = evt.item._cfg.model.class;
            // return className === 'case';
            return true;
          },
        });

        // 实例化 Minimap 插件
        const minimap = new G6.Minimap({
          size: [150, 100],
        });

        // 实例化 toolbar 插件
        const toolbar = new G6.ToolBar({
          //   getContent: () => {
          //     return `
          //        <ul class="g6-component-toolbar">
          //             <li code="redo">
          //             redo
          //             </li>
          //             <li code="undo">
          //             undo
          //             </li>
          //             <li code="zoomOut">
          //             zoomOut
          //             </li>
          //             <li code="zoomIn">
          //             zoomIn
          //             </li>
          //             <li code="realZoom">
          //             realZoom
          //             </li>
          //             <li code="autoZoom">
          //             autoZoom
          //             </li>
          //             <li code="refresh">
          //               refresh
          //             </li>
          //             <li code="screen">
          //              screen
          //             </li>
          //             <li code="save">
          //                save
          //             </li>
          //         </ul>
          //         `;
          //   },
          handleClick: (code, graph) => {
            const currentZoom = graph.getZoom();
            switch (code) {
              case 'redo':
                toolbar.redo();
                break;
              case 'undo':
                toolbar.undo();
                break;
              case 'zoomOut': {
                const ratioOut = 1 + 0.05 * 5;
                if (ratioOut * currentZoom > 5) {
                  return;
                }
                graph.zoomTo(currentZoom * 1.1);
                break;
              }
              case 'zoomIn': {
                const ratioIn = 1 - 0.05 * 5;
                if (ratioIn * currentZoom < 0.3) {
                  return;
                }
                graph.zoomTo(currentZoom * 0.9);
                break;
              }
              case 'realZoom':
                graph.zoomTo(1);
                break;
              case 'autoZoom':
                graph.fitView([20, 20]);
                break;
              case 'refresh':
                this.refresh();
                break;
              case 'screen':
                this.screenStatus = !this.screenStatus;
                // this.screenStatus ? fullScreen() : exitFullScreen();
                break;
              case 'save':
                this.download();
                break;
              default:
            }
          },
        });
        const layout = {
          ...layoutMap[this.layoutValue],
          center: [CANVAS_WIDTH / 2, CANVAS_HEIGHT / 2],
        };
        console.log('layout=', layout);
        graph = new G6.Graph({
          container: 'container',
          width: CANVAS_WIDTH,
          height: CANVAS_HEIGHT,
          modes: {
            default: [
              {
                type: 'zoom-canvas',
                sensitivity: 6,
                // minZoom:0.25,
                // maxZoom:2,
              },
              'drag-canvas',
              'drag-node',
            ],
          },
          minZoom: 0.25,
          maxZoom: 2,
          animate: true,
          animateCfg: {
            duration: 500, // Number，一次动画的时长
            // easing: 'linearEasing', // String，动画函数
          },
          defaultNode: {
            backgroundConfig: {
              backgroundType: 'circle',
              fill: ' #fff',
              stroke: '#40a9ff',
            },
            size: 20,
            style: {
              fill: '#fff',
              cursor: 'pointer',
            },
            labelCfg: {
              style: {
                fontSize: 12,
              },
            },
          },
          defaultEdge: {
            type: 'line',
            style: {
              lineWidth: 1,
              stroke: 'rgb(214, 214, 214)',
            },
            labelCfg: {
              style: {
                fill: '#fff',
              },
            },
          },
          //   linkCenter:false,
          //   fitCenter: true,
          nodeStateStyles: {},
          edgeStateStyles: {
            highlight: {
              lineWidth: 2,
              opacity: 1,
              stroke: '#f7bd32',
              labelCfg: {
                refY: -10,
                refX: 60,
                style: {
                  // stroke: 'white',  // 给文本添加白边和白色背景
                  // lineWidth: 5,     // 文本白边粗细
                  // fontSize: 16,
                  // color:"red",
                  fill: 'red', //标签的样式属性，文字颜色
                  // opacity:1,
                },
              },
            },
            normal: {
              opacity: 0.75,
              lineWidth: 1,
              stroke: 'rgb(214, 214, 214)',
            },
            dark: {
              opacity: 0.1,
              stroke: '#e3e3e3',
            },
          },
          plugins: [menu, minimap, toolbar], // 配置 Menu 插件
        });
        graph.updateLayout(layout);

        // graph.get("canvas").set("localRefresh", false);
      }
    },
    /**
     * 更新图谱实例
     */
    updateGraph(list) {
      currentGraphData = this.processNodesEdges(list);
      graph.changeData(currentGraphData);
    },
    /**
     * 创建图谱所需数据
     * @param {Object} reslut 接口返回数据
     */
    processNodesEdges(reslut) {
      let { nodeList: nodes, edgeList: edges } = cloneDeep(reslut);
      edges.forEach(edge => {
        edge.type = 'line';
      });
      let data = { nodes, edges };
      data.nodes.forEach(node => {
        let config = {};
        if (node.center) {
          //中心点样式特殊处理
          node.size = 30;
          config = Object.assign({}, styleMap[node.class], styleMap['center']);
        } else if (node.subCenter) {
          //副中心点样式特殊处理
          node.size = 30;
          config = Object.assign({}, styleMap[node.class], styleMap['subCenter']);
        } else {
          config = styleMap[node.class] ? styleMap[node.class] : styleMap['default'];
        }
        Object.assign(node, config);
      });
      return data;
    },
    /**
     * @description: 图谱事件绑定
     * @param {*}
     * @return {*}
     */
    bindListener() {
      graph.on('edge:click', e => {
        const cfg = e.item._cfg;
        this.codes = cfg.model.caseNos;
        const model = cfg.model;

        // const source = {
        //   name: cfg.source._cfg.model.name,
        //   value: cfg.source._cfg.model.value,
        // };
        // const target = {
        //   name: cfg.target._cfg.model.name,
        //   value: cfg.target._cfg.model.value,
        // };
        console.log('edge:cliclk', cfg.model);

        const source = model.source.split('_')[1];
        const target = model.target.split('_')[1];

        this.policeDrawerParams.inputParams = `${source}&${target}`;
        this.policeDrawerParams.caseNoList = model.caseNos;
        this.policeDrawerParams.seriesNo = this.reuteQuery.seriesNo;
        this.drawerVisible = true;

        //

        // const inputParams = `A-(${source.value}|${target.value})`;
      });
      graph.on('node:click', e => {
        const cfg = e.item._cfg;
        this.codes = cfg.model.caseNos;
        const inputParams = `A-(${cfg.model.value})`;
      });
      //   graph.on("node:click", (e)=> {
      //     this.focusNode = true;
      //     const item = e.item;
      //     graph.setAutoPaint(false);
      //     graph.getNodes().forEach(function(node) {
      //         // console.log('node',node)
      //       const hasSelectState = graphUtil.hasState(node,'_selected');
      //       if(!hasSelectState){
      //         graph.clearItemStates(node);
      //         graph.setItemState(node, "dark", true);
      //       }
      //         node.toBack();
      //     //   graph.setItemState(node, "selected", false);
      //     });
      //     graph.setItemState(item, "dark", false);
      //     item.toFront();

      //     graph.getEdges().forEach(function(edge) {
      //       if (edge.getSource()._cfg.id === item._cfg.id) {
      //         graph.setItemState(edge.getTarget(), "dark", false);
      //         graph.setItemState(edge.getTarget(), "highlight", true);
      //         graph.setItemState(edge, "highlight", true);
      //         // edge.getTarget().toFront();
      //         // edge.toFront();
      //       } else if (edge.getTarget()._cfg.id === item._cfg.id) {
      //         graph.setItemState(edge.getSource(), "dark", false);
      //         graph.setItemState(edge.getSource(), "highlight", true);
      //         graph.setItemState(edge, "highlight", true);
      //         graph.updateItem(edge.getSource(), { zIndex:2,});
      //         // edge.getSource().toFront();
      //         // edge.toFront();
      //       } else {
      //         graph.setItemState(edge, "highlight", false);
      //         graph.setItemState(edge, "dark", true);
      //       }
      //     });
      //     graph.paint();
      //     graph.setAutoPaint(true);
      //   });
      /**
       * 鼠标移入相关线高亮加粗,不直接关联的线置灰
       */
      graph.on('node:mouseenter', e => {
        console.log('mouseenter');
        // if (this.focusNode) return false;
        const item = e.item;

        const edges = item.getEdges();
        edges.forEach(edge => graph.setItemState(edge, 'highlight', true));

        graph.setAutoPaint(false);
        graph.getEdges().forEach(function (edge) {
          if (edge.getSource()._cfg.id === item._cfg.id) {
            graph.setItemState(edge, 'highlight', true);
            graph.setItemState(edge, 'normal', false);
            // edge.toFront();
          } else if (edge.getTarget()._cfg.id === item._cfg.id) {
            graph.setItemState(edge, 'highlight', true);
            graph.setItemState(edge, 'normal', false);
            // edge.toFront();
          } else {
            graph.setItemState(edge, 'highlight', false);
            graph.setItemState(edge, 'normal', true);
          }
        });
        graph.paint();
        graph.setAutoPaint(true);
      });
      graph.on('node:mouseleave', e => {
        const node = e.item;
        const edges = node.getEdges();
        edges.forEach(edge => graph.setItemState(edge, 'normal', false));

        // graph.getEdges().forEach(function (edge) {
        // edge.toBack();
        // });
        // if (this.focusNode) return false;
        this.setDefaultState();
      });
      //   graph.on('canvas:click', e => {
      //     this.focusNode = false;
      //     this.setDefaultState();
      //   });
      //   graph.on('wheelzoom', e => {
      //     this.zoomIndex = graph.getZoom();
      //   });
      // 布局完成
      graph.on('afterlayout', e => {
        console.log('布局完成');
        // document.getElementById('container').children[0].style.opacity = 1;
        // graph.fitCenter();
        // graph.fitView([20, 20]);
        // graph.fitCenter();
      });
    },
    /**
     * 渲染关系图
     * param {Object} list 渲染关系图所需数据
     */
    renderGraph(list) {
      currentGraphData = this.processNodesEdges(list);
      this.createGraph();
      //   const layoutConfig = layoutMap[this.layoutValue];
      //   layoutConfig.center = [CANVAS_WIDTH / 2, CANVAS_HEIGHT / 2];
      //   layout.instance = new G6.Layout[layoutConfig.type](layoutConfig);
      //   layout.instance.init({
      //     nodes: currentGraphData.nodes,
      //     edges: currentGraphData.edges,
      //   });
      //   layout.instance.execute();

      //   console.log('currentGraphData', currentGraphData);
      graph.data(currentGraphData);
      graph.render();
      //   graph.destroyLayout();
    },
    /**
     * 设置节点，线为默认状态
     */
    setDefaultState() {
      graph.setAutoPaint(false);
      graph.getNodes().forEach(function (node) {
        const hasSelectState = graphUtil.hasState(node, '_selected');
        if (!hasSelectState) {
          //   graph.clearItemStates(node);
          graph.setItemState(node, 'highlight', true);
        }
      });
      graph.getEdges().forEach(function (edge) {
        // graph.clearItemStates(edge);
        graph.setItemState(edge, 'normal', true);
      });
      graph.paint();
      graph.setAutoPaint(true);
    },
    /**
     * @description:
     * @param {*}
     * @return {*}
     */
    resizeHandle() {
      this.$nextTick(() => {
        if (this.$refs.forceContent && graph) {
          let width = this.$refs.forceContent.clientWidth;
          let height = this.$refs.forceContent.clientHeight;

          graph.changeSize(width, height);
          graph.fitCenter();
          graph.zoomTo(this.zoomIndex, { x: width / 2, y: height / 2 });
        }
      });
    },
  },
});
</script>

<style lang="less">
@import './css/index.less';
.graph-container {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 1;
  height: 100%;
}
</style>
